Nessa análise tive uma abordagem um pouco mais explicativa, em um formato similar ao de um tutorial ou artigo, voltada a um público que não tem familiaridade com a área dados. Escolhi isso por ser meu primeiro projeto de análise exploratória e por interesse em aproveitá-la para criar um artigo que será postado na plataforma Medium.
Primeiramente, precisamos entender o que é uma análise exploratória. A análise exploratória de dados (EDA) é o processo de examinar um conjunto de dados, buscando compreendê-lo de forma geral para entender suas principais características e padrões antes de aplicar técnicas mais avançadas de estatística ou de machine learning. Ele extremamente comum na rotina de Analistas e Cientistas de dados, sendo uma etapa bem importante nos projetos desenvolvidos desses profissionais.
Nesta análise, pretendo utilizar algumas funções da biblioteca Plotly, que nos permite criar gráficos interativos de maneira bem simples, e responder algumas e perguntas e hipóteses que criei sobre os dados com ajuda deles. Para manipular os dados utilizei a biblioteca Pandas do python no ambiente local do Jupyter Notebook do Anaconda Navigator.
Sobre os dados: Os dados que iremos analisar são do video-game de futebol FIFA 23. Todos os registros são sobre os jogadores contidos no jogo, como, por exemplo: Nome, Idade, Nome do Clube, Valor, Salário, Nacionalidade e Overall.
Um termo que será muito comum aqui será Overall (também chamado de rating) . Esse é o atributo principal de um jogador, que define sua qualidade geral. Ele varia normalmente entre 50 e 95, sendo que os considerados bons jogadores têm um valor de rating de 80 ou superior. Similiar a esse atributo, temos o Overall potencial , que é o valor de rating máximo, definido pelos desenvolvedores, que um jogador pode atingir em sua carreira. Ele costuma ser elevado para jogadores mais jovens e igual, ou pouco superior, para jogadores mais velhos. Além desses, existem diversos atributos que medem os atributos físicos, de habilidade e mentais dos atletas. Uma explicação mais detalhada sobre alguns deles pode ser encontrada neste link: https://fifauteam.com/fifa-23-attributes/
Importante lembrar que, o FIFA 23 não possui todos os jogadores profissionais registrados em sua base de dados (como os jogadores das ligas brasileiras, por exemplo), já que nem todas as ligas possuem contrato com a empresa desenvolvedora (EA Sports). Isso faz com que os dados não retratem 100% da realidade do futebol internacional, pois, além de não termos todos os atletas, naturalmente existem algumas imprecisões sobre a medição os atributos, e questionamentos se eles realmente correspondem as habilidades dos jogadores dentro de campo. Apesar dessas ressalvas, o Dataset (conjunto de dados) é bem completo e viável para ser feita uma boa análise.
Fonte dos dados: https://www.kaggle.com/datasets/sanjeetsinghnaik/fifa-23-players-dataset Autor: Sanjeetsinghnaik (Usuário do site "Kaggle")
Para guiar nossa análise exploratória
Perguntas e Hipóteses:
#Importando as bibliotecas
import pandas as pd
import plotly.express as px
import plotly.figure_factory as ff
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import plotly.offline as pyo
pyo.init_notebook_mode(connected=True)
#Carregando dataset
df = pd.read_csv('Fifa 23 Players Data-Copy1.csv')
pd.set_option('display.max_columns', None)
#Removendo colunas desnecessárias para a análise
df.drop(['Image Link', 'National Team Image Link', 'National Team Jersey Number', 'Attacking Work Rate'
, 'Defensive Work Rate', 'Contract Until', 'Joined On', 'On Loan', 'Skill Moves', 'Weak Foot Rating',
'International Reputation'], 1, inplace = True)
#Mudando o nome de duas colunas para facilitar o uso
df.rename(columns={'Value(in Euro)':'Value','Wage(in Euro)':'Wage'}, inplace=True)
C:\Users\joaoi\AppData\Local\Temp\ipykernel_1292\212389229.py:7: FutureWarning: In a future version of pandas all arguments of DataFrame.drop except for the argument 'labels' will be keyword-only.
df.head()
| Known As | Full Name | Overall | Potential | Value | Positions Played | Best Position | Nationality | Age | Height(in cm) | Weight(in kg) | TotalStats | BaseStats | Club Name | Wage | Release Clause | Club Position | Club Jersey Number | Preferred Foot | National Team Name | National Team Position | Pace Total | Shooting Total | Passing Total | Dribbling Total | Defending Total | Physicality Total | Crossing | Finishing | Heading Accuracy | Short Passing | Volleys | Dribbling | Curve | Freekick Accuracy | LongPassing | BallControl | Acceleration | Sprint Speed | Agility | Reactions | Balance | Shot Power | Jumping | Stamina | Strength | Long Shots | Aggression | Interceptions | Positioning | Vision | Penalties | Composure | Marking | Standing Tackle | Sliding Tackle | Goalkeeper Diving | Goalkeeper Handling | GoalkeeperKicking | Goalkeeper Positioning | Goalkeeper Reflexes | ST Rating | LW Rating | LF Rating | CF Rating | RF Rating | RW Rating | CAM Rating | LM Rating | CM Rating | RM Rating | LWB Rating | CDM Rating | RWB Rating | LB Rating | CB Rating | RB Rating | GK Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | L. Messi | Lionel Messi | 91 | 91 | 54000000 | RW | CAM | Argentina | 35 | 169 | 67 | 2190 | 452 | Paris Saint-Germain | 195000 | 99900000 | RW | 30 | Left | Argentina | RW | 81 | 89 | 90 | 94 | 34 | 64 | 84 | 90 | 70 | 91 | 88 | 95 | 93 | 93 | 90 | 93 | 87 | 76 | 91 | 92 | 95 | 86 | 68 | 70 | 68 | 91 | 44 | 40 | 93 | 94 | 75 | 96 | 20 | 35 | 24 | 6 | 11 | 15 | 14 | 8 | 90 | 90 | 91 | 91 | 91 | 90 | 91 | 91 | 88 | 91 | 67 | 66 | 67 | 62 | 53 | 62 | 22 |
| 1 | K. Benzema | Karim Benzema | 91 | 91 | 64000000 | CF,ST | CF | France | 34 | 185 | 81 | 2147 | 455 | Real Madrid CF | 450000 | 131199999 | CF | 9 | Right | France | ST | 80 | 88 | 83 | 87 | 39 | 78 | 75 | 92 | 90 | 89 | 88 | 87 | 82 | 73 | 76 | 91 | 79 | 80 | 78 | 92 | 72 | 87 | 79 | 82 | 82 | 80 | 63 | 39 | 92 | 89 | 84 | 90 | 43 | 24 | 18 | 13 | 11 | 5 | 5 | 7 | 91 | 87 | 89 | 89 | 89 | 87 | 91 | 89 | 84 | 89 | 67 | 67 | 67 | 63 | 58 | 63 | 21 |
| 2 | R. Lewandowski | Robert Lewandowski | 91 | 91 | 84000000 | ST | ST | Poland | 33 | 185 | 81 | 2205 | 458 | FC Barcelona | 420000 | 172200000 | ST | 9 | Right | Poland | ST | 75 | 91 | 79 | 86 | 44 | 83 | 71 | 94 | 91 | 84 | 89 | 85 | 79 | 85 | 70 | 89 | 76 | 75 | 77 | 93 | 82 | 91 | 85 | 76 | 87 | 84 | 81 | 49 | 94 | 81 | 90 | 88 | 35 | 42 | 19 | 15 | 6 | 12 | 8 | 10 | 91 | 85 | 88 | 88 | 88 | 85 | 88 | 86 | 83 | 86 | 67 | 69 | 67 | 64 | 63 | 64 | 22 |
| 3 | K. De Bruyne | Kevin De Bruyne | 91 | 91 | 107500000 | CM,CAM | CM | Belgium | 31 | 181 | 70 | 2303 | 483 | Manchester City | 350000 | 198900000 | CM | 17 | Right | Belgium | RF | 74 | 88 | 93 | 87 | 64 | 77 | 94 | 85 | 55 | 93 | 83 | 88 | 89 | 83 | 93 | 90 | 76 | 73 | 76 | 91 | 78 | 92 | 63 | 88 | 74 | 91 | 75 | 66 | 88 | 94 | 83 | 89 | 68 | 65 | 53 | 15 | 13 | 5 | 10 | 13 | 86 | 88 | 87 | 87 | 87 | 88 | 91 | 91 | 91 | 91 | 82 | 82 | 82 | 78 | 72 | 78 | 24 |
| 4 | K. Mbappé | Kylian Mbappé | 91 | 95 | 190500000 | ST,LW | ST | France | 23 | 182 | 73 | 2177 | 470 | Paris Saint-Germain | 230000 | 366700000 | ST | 7 | Right | France | ST | 97 | 89 | 80 | 92 | 36 | 76 | 78 | 93 | 72 | 85 | 83 | 93 | 80 | 69 | 71 | 91 | 97 | 97 | 93 | 93 | 81 | 88 | 77 | 87 | 76 | 82 | 64 | 38 | 92 | 83 | 80 | 88 | 26 | 34 | 32 | 13 | 5 | 7 | 11 | 6 | 92 | 90 | 90 | 90 | 90 | 90 | 92 | 92 | 84 | 92 | 70 | 66 | 70 | 66 | 57 | 66 | 21 |
df.tail()
| Known As | Full Name | Overall | Potential | Value | Positions Played | Best Position | Nationality | Age | Height(in cm) | Weight(in kg) | TotalStats | BaseStats | Club Name | Wage | Release Clause | Club Position | Club Jersey Number | Preferred Foot | National Team Name | National Team Position | Pace Total | Shooting Total | Passing Total | Dribbling Total | Defending Total | Physicality Total | Crossing | Finishing | Heading Accuracy | Short Passing | Volleys | Dribbling | Curve | Freekick Accuracy | LongPassing | BallControl | Acceleration | Sprint Speed | Agility | Reactions | Balance | Shot Power | Jumping | Stamina | Strength | Long Shots | Aggression | Interceptions | Positioning | Vision | Penalties | Composure | Marking | Standing Tackle | Sliding Tackle | Goalkeeper Diving | Goalkeeper Handling | GoalkeeperKicking | Goalkeeper Positioning | Goalkeeper Reflexes | ST Rating | LW Rating | LF Rating | CF Rating | RF Rating | RW Rating | CAM Rating | LM Rating | CM Rating | RM Rating | LWB Rating | CDM Rating | RWB Rating | LB Rating | CB Rating | RB Rating | GK Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 18534 | D. Collins | Darren Collins | 47 | 56 | 110000 | ST,RM | CAM | Republic of Ireland | 21 | 174 | 68 | 1287 | 274 | Sligo Rovers | 500 | 193000 | RES | 20 | Right | - | - | 68 | 48 | 43 | 51 | 31 | 33 | 40 | 49 | 30 | 42 | 48 | 50 | 53 | 50 | 33 | 48 | 69 | 68 | 59 | 44 | 63 | 50 | 45 | 32 | 31 | 46 | 37 | 22 | 50 | 52 | 40 | 47 | 39 | 29 | 27 | 6 | 9 | 5 | 13 | 8 | 49 | 50 | 50 | 50 | 50 | 50 | 51 | 50 | 44 | 50 | 41 | 38 | 41 | 40 | 36 | 40 | 15 |
| 18535 | Yang Dejiang | Dejiang Yang | 47 | 57 | 90000 | CDM | CDM | China PR | 17 | 175 | 60 | 1289 | 267 | Guangzhou FC | 500 | 158000 | SUB | 30 | Right | - | - | 55 | 37 | 41 | 47 | 48 | 39 | 34 | 33 | 44 | 46 | 31 | 42 | 32 | 31 | 45 | 46 | 52 | 57 | 59 | 51 | 80 | 50 | 55 | 34 | 35 | 35 | 52 | 46 | 35 | 40 | 33 | 45 | 46 | 50 | 52 | 6 | 12 | 11 | 8 | 6 | 44 | 43 | 43 | 43 | 43 | 43 | 45 | 45 | 45 | 45 | 47 | 48 | 47 | 49 | 49 | 49 | 15 |
| 18536 | L. Mullan | Liam Mullan | 47 | 67 | 130000 | CM | RM | Northern Ireland | 18 | 170 | 65 | 1333 | 277 | Derry City | 500 | 332000 | SUB | 38 | Right | - | - | 64 | 40 | 49 | 52 | 37 | 35 | 41 | 36 | 42 | 54 | 37 | 52 | 47 | 42 | 52 | 50 | 70 | 59 | 46 | 49 | 73 | 54 | 54 | 36 | 31 | 36 | 39 | 24 | 42 | 50 | 43 | 59 | 39 | 37 | 48 | 11 | 12 | 8 | 7 | 12 | 48 | 49 | 49 | 49 | 49 | 49 | 51 | 52 | 49 | 52 | 46 | 44 | 46 | 46 | 42 | 46 | 17 |
| 18537 | D. McCallion | Daithí McCallion | 47 | 61 | 100000 | CB | CB | Republic of Ireland | 17 | 178 | 65 | 1113 | 226 | Derry City | 500 | 218000 | SUB | 37 | Right | - | - | 52 | 24 | 25 | 32 | 52 | 41 | 21 | 20 | 41 | 25 | 27 | 27 | 26 | 20 | 22 | 26 | 53 | 51 | 42 | 43 | 66 | 34 | 72 | 49 | 34 | 18 | 42 | 54 | 23 | 32 | 37 | 41 | 50 | 54 | 54 | 8 | 14 | 13 | 7 | 8 | 33 | 30 | 30 | 30 | 30 | 30 | 31 | 33 | 33 | 33 | 44 | 42 | 44 | 47 | 49 | 47 | 15 |
| 18538 | N. Rabha | Nabin Rabha | 47 | 50 | 60000 | LB | LB | India | 25 | 176 | 66 | 1277 | 269 | NorthEast United FC | 500 | 86000 | RES | 25 | Left | - | - | 61 | 29 | 35 | 46 | 44 | 54 | 38 | 28 | 41 | 35 | 29 | 47 | 33 | 32 | 29 | 38 | 70 | 53 | 58 | 45 | 76 | 29 | 66 | 56 | 55 | 28 | 47 | 40 | 36 | 39 | 35 | 32 | 47 | 44 | 43 | 13 | 13 | 6 | 14 | 14 | 41 | 42 | 40 | 40 | 40 | 42 | 42 | 44 | 40 | 44 | 46 | 43 | 46 | 47 | 47 | 47 | 19 |
print("Este dataset possui {} linhas e {} colunas".format(df.shape[0],df.shape[1]))
Este dataset possui 18539 linhas e 78 colunas
#Valores únicos de cada coluna
df.nunique()
Known As 17530
Full Name 18337
Overall 45
Potential 48
Value 257
...
RWB Rating 72
LB Rating 71
CB Rating 73
RB Rating 71
GK Rating 64
Length: 78, dtype: int64
df.info()
<class 'pandas.core.frame.DataFrame'> RangeIndex: 18539 entries, 0 to 18538 Data columns (total 78 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 Known As 18539 non-null object 1 Full Name 18539 non-null object 2 Overall 18539 non-null int64 3 Potential 18539 non-null int64 4 Value 18539 non-null int64 5 Positions Played 18539 non-null object 6 Best Position 18539 non-null object 7 Nationality 18539 non-null object 8 Age 18539 non-null int64 9 Height(in cm) 18539 non-null int64 10 Weight(in kg) 18539 non-null int64 11 TotalStats 18539 non-null int64 12 BaseStats 18539 non-null int64 13 Club Name 18539 non-null object 14 Wage 18539 non-null int64 15 Release Clause 18539 non-null int64 16 Club Position 18539 non-null object 17 Club Jersey Number 18539 non-null object 18 Preferred Foot 18539 non-null object 19 National Team Name 18539 non-null object 20 National Team Position 18539 non-null object 21 Pace Total 18539 non-null int64 22 Shooting Total 18539 non-null int64 23 Passing Total 18539 non-null int64 24 Dribbling Total 18539 non-null int64 25 Defending Total 18539 non-null int64 26 Physicality Total 18539 non-null int64 27 Crossing 18539 non-null int64 28 Finishing 18539 non-null int64 29 Heading Accuracy 18539 non-null int64 30 Short Passing 18539 non-null int64 31 Volleys 18539 non-null int64 32 Dribbling 18539 non-null int64 33 Curve 18539 non-null int64 34 Freekick Accuracy 18539 non-null int64 35 LongPassing 18539 non-null int64 36 BallControl 18539 non-null int64 37 Acceleration 18539 non-null int64 38 Sprint Speed 18539 non-null int64 39 Agility 18539 non-null int64 40 Reactions 18539 non-null int64 41 Balance 18539 non-null int64 42 Shot Power 18539 non-null int64 43 Jumping 18539 non-null int64 44 Stamina 18539 non-null int64 45 Strength 18539 non-null int64 46 Long Shots 18539 non-null int64 47 Aggression 18539 non-null int64 48 Interceptions 18539 non-null int64 49 Positioning 18539 non-null int64 50 Vision 18539 non-null int64 51 Penalties 18539 non-null int64 52 Composure 18539 non-null int64 53 Marking 18539 non-null int64 54 Standing Tackle 18539 non-null int64 55 Sliding Tackle 18539 non-null int64 56 Goalkeeper Diving 18539 non-null int64 57 Goalkeeper Handling 18539 non-null int64 58 GoalkeeperKicking 18539 non-null int64 59 Goalkeeper Positioning 18539 non-null int64 60 Goalkeeper Reflexes 18539 non-null int64 61 ST Rating 18539 non-null int64 62 LW Rating 18539 non-null int64 63 LF Rating 18539 non-null int64 64 CF Rating 18539 non-null int64 65 RF Rating 18539 non-null int64 66 RW Rating 18539 non-null int64 67 CAM Rating 18539 non-null int64 68 LM Rating 18539 non-null int64 69 CM Rating 18539 non-null int64 70 RM Rating 18539 non-null int64 71 LWB Rating 18539 non-null int64 72 CDM Rating 18539 non-null int64 73 RWB Rating 18539 non-null int64 74 LB Rating 18539 non-null int64 75 CB Rating 18539 non-null int64 76 RB Rating 18539 non-null int64 77 GK Rating 18539 non-null int64 dtypes: int64(67), object(11) memory usage: 11.0+ MB
df.isnull().sum()
Known As 0
Full Name 0
Overall 0
Potential 0
Value 0
..
RWB Rating 0
LB Rating 0
CB Rating 0
RB Rating 0
GK Rating 0
Length: 78, dtype: int64
O Dataset não possui valores nulos e nem dados a serem tratados. 67 colunas são do tipo inteiro e 11 do tipo objeto (palavras).
df.describe()
| Overall | Potential | Value | Age | Height(in cm) | Weight(in kg) | TotalStats | BaseStats | Wage | Release Clause | Pace Total | Shooting Total | Passing Total | Dribbling Total | Defending Total | Physicality Total | Crossing | Finishing | Heading Accuracy | Short Passing | Volleys | Dribbling | Curve | Freekick Accuracy | LongPassing | BallControl | Acceleration | Sprint Speed | Agility | Reactions | Balance | Shot Power | Jumping | Stamina | Strength | Long Shots | Aggression | Interceptions | Positioning | Vision | Penalties | Composure | Marking | Standing Tackle | Sliding Tackle | Goalkeeper Diving | Goalkeeper Handling | GoalkeeperKicking | Goalkeeper Positioning | Goalkeeper Reflexes | ST Rating | LW Rating | LF Rating | CF Rating | RF Rating | RW Rating | CAM Rating | LM Rating | CM Rating | RM Rating | LWB Rating | CDM Rating | RWB Rating | LB Rating | CB Rating | RB Rating | GK Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| count | 18539.000000 | 18539.000000 | 1.853900e+04 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 1.853900e+04 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 | 18539.000000 |
| mean | 65.852042 | 71.016668 | 2.875461e+06 | 25.240412 | 181.550839 | 75.173904 | 1602.114569 | 357.946221 | 8824.537462 | 5.081688e+06 | 68.017746 | 53.777874 | 58.024327 | 63.109553 | 50.241383 | 64.775338 | 49.476833 | 46.255300 | 51.846755 | 59.072226 | 42.513944 | 55.898754 | 47.695129 | 43.006689 | 53.568423 | 58.516263 | 64.725336 | 64.838341 | 63.518906 | 61.542586 | 64.059550 | 57.827661 | 64.795566 | 63.040455 | 65.152004 | 46.825719 | 55.668537 | 46.853282 | 50.520362 | 54.191542 | 47.994444 | 58.036625 | 46.747505 | 48.399159 | 46.264146 | 16.402125 | 16.157182 | 16.061007 | 16.205944 | 16.472895 | 56.725929 | 55.819138 | 55.714925 | 55.714925 | 55.714925 | 55.819138 | 57.950267 | 58.451319 | 57.374076 | 58.451319 | 56.281569 | 55.928583 | 56.281569 | 55.650251 | 54.528184 | 55.650251 | 23.257134 |
| std | 6.788353 | 6.192866 | 7.635129e+06 | 4.718163 | 6.858097 | 7.013593 | 273.160237 | 39.628259 | 19460.531154 | 1.467203e+07 | 10.649511 | 13.619867 | 9.717950 | 9.336566 | 16.392532 | 9.577715 | 17.887405 | 19.623881 | 17.318947 | 14.287698 | 17.635249 | 18.751691 | 17.910205 | 16.997758 | 14.633838 | 16.590051 | 15.280849 | 15.108259 | 14.905330 | 8.900297 | 14.483193 | 12.949870 | 12.293523 | 16.269330 | 12.622774 | 19.362064 | 16.905505 | 20.666647 | 19.660034 | 13.478006 | 15.730026 | 12.036272 | 20.350228 | 21.191644 | 20.701146 | 17.589457 | 16.924266 | 16.680839 | 17.089109 | 17.927602 | 13.475267 | 14.632018 | 14.216500 | 14.216500 | 14.216500 | 14.632018 | 13.905442 | 13.987122 | 13.171194 | 13.987122 | 13.903836 | 13.872190 | 13.903836 | 14.159466 | 14.743929 | 14.159466 | 15.108925 |
| min | 47.000000 | 48.000000 | 0.000000e+00 | 16.000000 | 155.000000 | 49.000000 | 759.000000 | 224.000000 | 0.000000 | 0.000000e+00 | 28.000000 | 16.000000 | 25.000000 | 28.000000 | 15.000000 | 30.000000 | 6.000000 | 3.000000 | 5.000000 | 10.000000 | 3.000000 | 3.000000 | 6.000000 | 4.000000 | 9.000000 | 5.000000 | 14.000000 | 15.000000 | 18.000000 | 30.000000 | 20.000000 | 18.000000 | 22.000000 | 14.000000 | 25.000000 | 4.000000 | 10.000000 | 3.000000 | 2.000000 | 10.000000 | 6.000000 | 13.000000 | 3.000000 | 6.000000 | 6.000000 | 2.000000 | 2.000000 | 2.000000 | 2.000000 | 2.000000 | 19.000000 | 14.000000 | 15.000000 | 15.000000 | 15.000000 | 14.000000 | 17.000000 | 18.000000 | 18.000000 | 18.000000 | 17.000000 | 19.000000 | 17.000000 | 17.000000 | 18.000000 | 17.000000 | 10.000000 |
| 25% | 62.000000 | 67.000000 | 4.750000e+05 | 21.000000 | 177.000000 | 70.000000 | 1470.000000 | 331.000000 | 1000.000000 | 6.650000e+05 | 62.000000 | 44.000000 | 52.000000 | 58.000000 | 36.000000 | 58.000000 | 39.000000 | 31.000000 | 44.000000 | 55.000000 | 30.000000 | 51.000000 | 36.000000 | 32.000000 | 45.000000 | 55.000000 | 57.000000 | 57.000000 | 55.000000 | 56.000000 | 56.000000 | 48.000000 | 57.000000 | 56.000000 | 57.000000 | 32.000000 | 45.000000 | 26.000000 | 40.000000 | 45.000000 | 39.000000 | 51.000000 | 29.000000 | 28.000000 | 26.000000 | 8.000000 | 8.000000 | 8.000000 | 8.000000 | 8.000000 | 51.000000 | 50.000000 | 50.000000 | 50.000000 | 50.000000 | 50.000000 | 52.000000 | 54.000000 | 53.000000 | 54.000000 | 51.000000 | 48.000000 | 51.000000 | 49.000000 | 45.000000 | 49.000000 | 17.000000 |
| 50% | 66.000000 | 71.000000 | 1.000000e+06 | 25.000000 | 182.000000 | 75.000000 | 1640.000000 | 358.000000 | 3000.000000 | 1.500000e+06 | 69.000000 | 56.000000 | 59.000000 | 64.000000 | 54.000000 | 66.000000 | 54.000000 | 50.000000 | 55.000000 | 62.000000 | 44.000000 | 61.000000 | 49.000000 | 42.000000 | 56.000000 | 63.000000 | 68.000000 | 68.000000 | 66.000000 | 62.000000 | 66.000000 | 59.000000 | 65.000000 | 66.000000 | 66.000000 | 51.000000 | 58.000000 | 54.000000 | 56.000000 | 56.000000 | 49.000000 | 59.000000 | 53.000000 | 56.000000 | 53.000000 | 11.000000 | 11.000000 | 11.000000 | 11.000000 | 11.000000 | 60.000000 | 59.000000 | 59.000000 | 59.000000 | 59.000000 | 59.000000 | 61.000000 | 62.000000 | 60.000000 | 62.000000 | 59.000000 | 59.000000 | 59.000000 | 59.000000 | 58.000000 | 59.000000 | 18.000000 |
| 75% | 70.000000 | 75.000000 | 2.000000e+06 | 29.000000 | 186.000000 | 80.000000 | 1786.000000 | 385.000000 | 8000.000000 | 3.400000e+06 | 75.000000 | 64.000000 | 65.000000 | 69.000000 | 64.000000 | 72.000000 | 63.000000 | 62.000000 | 64.000000 | 68.000000 | 56.000000 | 68.000000 | 61.000000 | 55.000000 | 64.000000 | 69.000000 | 75.000000 | 75.000000 | 74.000000 | 67.000000 | 74.000000 | 68.000000 | 73.000000 | 74.000000 | 74.000000 | 62.000000 | 68.000000 | 64.000000 | 64.000000 | 64.000000 | 60.000000 | 66.000000 | 63.000000 | 66.000000 | 63.000000 | 14.000000 | 14.000000 | 14.000000 | 14.000000 | 14.000000 | 66.000000 | 65.000000 | 65.000000 | 65.000000 | 65.000000 | 65.000000 | 67.000000 | 67.000000 | 66.000000 | 67.000000 | 66.000000 | 66.000000 | 66.000000 | 65.000000 | 66.000000 | 65.000000 | 20.000000 |
| max | 91.000000 | 95.000000 | 1.905000e+08 | 44.000000 | 206.000000 | 105.000000 | 2312.000000 | 502.000000 | 450000.000000 | 3.667000e+08 | 97.000000 | 92.000000 | 93.000000 | 94.000000 | 91.000000 | 91.000000 | 94.000000 | 94.000000 | 93.000000 | 93.000000 | 90.000000 | 95.000000 | 93.000000 | 94.000000 | 93.000000 | 94.000000 | 97.000000 | 97.000000 | 94.000000 | 94.000000 | 95.000000 | 94.000000 | 95.000000 | 95.000000 | 96.000000 | 91.000000 | 95.000000 | 91.000000 | 96.000000 | 94.000000 | 92.000000 | 96.000000 | 92.000000 | 93.000000 | 90.000000 | 90.000000 | 90.000000 | 93.000000 | 91.000000 | 90.000000 | 92.000000 | 90.000000 | 91.000000 | 91.000000 | 91.000000 | 90.000000 | 92.000000 | 92.000000 | 91.000000 | 92.000000 | 88.000000 | 89.000000 | 88.000000 | 87.000000 | 90.000000 | 87.000000 | 90.000000 |
Agora que temos uma visão geral sobre como os dados são, podemos analisar de forma mais específica, começando pela análise univariada.
Análise de certas variáveis individualmente, vendo suas quantidades e distribuições.
#Criando um gráfico de barra
fig = px.bar(df.Nationality.value_counts().head(10), y = 'Nationality',title = 'Países com mais jogadores no Game')
fig.update_layout(xaxis_title = 'Países')
fig.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig)
--------------------------------------------------------------------------- ValueError Traceback (most recent call last) Cell In[40], line 6 4 fig.update_layout(yaxis_title = 'Quantidade') 5 pyo.iplot(fig) ----> 6 fig.write_image("plot.png") File ~\anaconda3\lib\site-packages\plotly\basedatatypes.py:3829, in BaseFigure.write_image(self, *args, **kwargs) 3769 """ 3770 Convert a figure to a static image and write it to a file or writeable 3771 object (...) 3825 None 3826 """ 3827 import plotly.io as pio -> 3829 return pio.write_image(self, *args, **kwargs) File ~\anaconda3\lib\site-packages\plotly\io\_kaleido.py:268, in write_image(fig, file, format, scale, width, height, validate, engine) 252 raise ValueError( 253 """ 254 Cannot infer image type from output path '{file}'. (...) 262 ) 263 ) 265 # Request image 266 # ------------- 267 # Do this first so we don't create a file if image conversion fails --> 268 img_data = to_image( 269 fig, 270 format=format, 271 scale=scale, 272 width=width, 273 height=height, 274 validate=validate, 275 engine=engine, 276 ) 278 # Open file 279 # --------- 280 if path is None: 281 # We previously failed to make sense of `file` as a pathlib object. 282 # Attempt to write to `file` as an open file descriptor. File ~\anaconda3\lib\site-packages\plotly\io\_kaleido.py:134, in to_image(fig, format, width, height, scale, validate, engine) 132 # Raise informative error message if Kaleido is not installed 133 if scope is None: --> 134 raise ValueError( 135 """ 136 Image export using the "kaleido" engine requires the kaleido package, 137 which can be installed using pip: 138 $ pip install -U kaleido 139 """ 140 ) 142 # Validate figure 143 # --------------- 144 fig_dict = validate_coerce_fig_to_dict(fig, validate) ValueError: Image export using the "kaleido" engine requires the kaleido package, which can be installed using pip: $ pip install -U kaleido
O Fato de a Inglaterra possuir mais jogadores registrados não quer dizer necessariamente que o país possui a maior quantidade de jogadores profissionais - apesar dos vários indícios para isso. Essa grande quantidade existe porque existem muitas ligas inglesas inferiores cadastradas no jogo. Ao contrário, por exemplo, do Brasil, que possui não possui nenhuma liga nacional registrada de forma oficial (apenas com alguns jogadores gerados pelo jogo).
#Criando uma função que gera um conjunto de gráficos
fig2 = make_subplots(rows =2 , cols =2)
#Adicionando gráficos de histograma
fig2.add_trace(go.Histogram(x=df['Overall'], name = "Distribuição de Overall por jogadores") ,row =1, col=1)
fig2.add_trace(go.Histogram(x=df['Potential'], name = "Distribuição de Potencial dos jogadores") ,row =1, col=2)
fig2.add_trace(go.Histogram(x=df['Overall'], name = 'Overall') ,row =2, col=1)
fig2.add_trace(go.Histogram(x=df['Potential'], name = 'Potencial') ,row =2, col=1)
#Mudando suas características
fig2.update_xaxes(title_text="Overall", row=1, col=1)
fig2.update_xaxes(title_text="Potencial", row=1, col=2)
fig2.update_xaxes(title_text="Overall x Potencial", row=2, col=1)
fig2.update_layout(height=900, width=1000)
pyo.iplot(fig2)
Para vermos os jogadores com maiores ratings por posição , criei duas funções: uma para achar o nome e outro o rating do jogador. Por fim criando uma tabela (DataFrame) com todas essas informações.
#Função para retornar os nomes do jogadores
def get_max_name(df, col):
return df.iloc[df[col].idxmax(), 0]
#Função para retornar os maiores ratings
def get_max_rat(df, col):
return list(df.loc[df[col].max(), col].index)
#Criando variáveis com os nomes e ratings maiores
max_names = get_max_name(df,df.columns[61:78])
max_rats = get_max_rat(df, df.columns[61:78])
#Criando Dataframe com as variáveis importantes
top_ply = pd.DataFrame({'Jogador':max_names, 'Posição': df.columns[61:78], 'Rating' : max_rats})
top_ply
| Jogador | Posição | Rating | |
|---|---|---|---|
| 4 | K. Mbappé | ST Rating | 92 |
| 0 | L. Messi | LW Rating | 90 |
| 0 | L. Messi | LF Rating | 91 |
| 0 | L. Messi | CF Rating | 91 |
| 0 | L. Messi | RF Rating | 91 |
| 0 | L. Messi | RW Rating | 90 |
| 4 | K. Mbappé | CAM Rating | 92 |
| 4 | K. Mbappé | LM Rating | 92 |
| 3 | K. De Bruyne | CM Rating | 91 |
| 4 | K. Mbappé | RM Rating | 92 |
| 24 | João Cancelo | LWB Rating | 88 |
| 13 | Casemiro | CDM Rating | 89 |
| 24 | João Cancelo | RWB Rating | 88 |
| 19 | N. Kanté | LB Rating | 87 |
| 9 | V. van Dijk | CB Rating | 90 |
| 19 | N. Kanté | RB Rating | 87 |
| 6 | T. Courtois | GK Rating | 90 |
#Criando histograma para ver a distribuição de idade
fig3 = px.histogram(df, x = 'Age',title = 'Distribuição de Idade')
fig3.update_layout(xaxis_title = 'Idade')
fig3.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig3)
Diversos jogadores podem atuar bem em posições diferentes, mas vamos ver quais são as mais comuns pelo atributo "Best Position", que contém a melhor posição que os atletas podem atuar.
#Criando gráfico com as posições mais frequentes no jogo
fig4 = px.histogram(df, x = 'Best Position', color = 'Best Position', title = 'Posições mais frequentes')
fig4.update_layout(xaxis_title = 'Melhor Posição')
fig4.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig4)
Vemos que, as quatro posições com mais jogadores especialistas são CB (Center back) que significa zagueiro, ST (Striker) atacante, CAM (Central Attack Midfielder) meio-campista avançado e GK (Goalkeeper).
Para verificarmos quais países possuem as maiores médias de overall, temos que nos atentar ao fato de que existem alguns países com poucos jogadores, fazendo com que eles tenham uma média maior mesmo sem possuir realmente bons jogadores ou alguma relevância no esporte. Por isso, analisaremos apenas as médias de países possuem pelo menos 150 jogadores no jogo. Para isso, criei um dataframe (dfb) com as nações e a quantidade de jogadores em cada uma para poder extrair apenas seus nomes e aplicar a função "isin", selecionando só jogadores dessas nações.
# Criando dataframe com países de pelo menos 150 jogadores
dfb = df.groupby("Nationality").size().reset_index(name='counts')
dfb = dfb[dfb['counts'] > 150]
# Lista contendo os países com mais de 150 jogadores
b = dfb.iloc[:, 0]
dfb = df[df['Nationality'].isin(b)]
# Gerando gráfico
ovr_nat = dfb.groupby('Nationality').Overall.mean().sort_values(ascending = False)
fig5 = px.bar(ovr_nat.head(10), title = 'Países por média de Overall')
fig5.update_layout(xaxis_title = 'Nacionalidade')
fig5.update_layout(yaxis_title = 'Média de OVR')
pyo.iplot(fig5)
Mesmo filtrando os países, ainda temos países com médias que não condizem exatamente com a qualidade geral de suas seleções. Isso acontece porque, como vimos anteriormente, países com França, Alemanha e Inglaterra (três dos mais tradicionais) têm muitos jogadores, o que os faz ter uma média de Overall menor, já que têm jogadores em ligar inferiores. Outra forma de atingir o mesmo objetivo (talvez até melhor) é contar a quantidade de jogadores com mais de 70 de Overall por cada país. Dessa forma, temos um retrato mais fiel da realidade, com os países considerados mais talentosos acima - incluindo o Brasil em primeiro :).
#Criando dataframe com apenas jogadores de pelo menos 70 de Overall e de países com pelo menos 150 jogadores
dfb = df.groupby("Nationality").size().reset_index(name='counts')
dfc = dfb[dfb['counts'] > 150]
dfc = df[df['Nationality'].isin(dfb['Nationality'])]
dfc = dfc[dfc['Overall'] > 70]
#Criando variável com a quantidade de jogadores por país e um gráfico de barras
ovr_count = dfc['Nationality'].value_counts()
fig8 = px.bar(ovr_count.head(10))
fig8.update_traces(marker=dict(color='yellow'))
fig8.update_layout(xaxis_title = 'Nacionalidade')
fig8.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig8)
Seguindo a mesma métrica, veremos os países com maior overall potencial (promessas), ou seja, os que têm mais jogadores promissores, que o FIFA prevê que iram evoluir mais no futuro e se tornarem bons jogadores. Escolheremos apenas os que tem potencial maior que 80 e que possuem menos de 23 anos.
#Criando variável contendo jogadores com no máximo 23 anos e potencial de pelo menos 80 de Overall
prom = df[(df['Potential'] >= 80) & (df['Age'] <= 23)]
prom = prom['Nationality'].value_counts()
#Criando gráfico
fig9 = px.bar(prom.head(10), title = 'Países com jogadores jovens acima de 80 de Overall potencial')
fig9.update_traces(marker=dict(color='blue'))
fig9.update_layout(xaxis_title = 'Países')
fig9.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig9)
Agora contando jogadores com potencial de se tornarem grandes estrelas, com 90 ou mais de overall potencial.
#Criando variável contendo jogadores com no máximo 23 anos e Overall potencial de 90
stars = df[(df['Potential'] >= 90) & (df['Age'] <= 23)]
stars = stars['Nationality'].value_counts()
#Criando gráfico
fig10 = px.bar(stars.head(10), title = 'Países com mais jogadores com 90 ou mais de Overall')
fig10.update_traces(marker=dict(color='green'))
fig10.update_layout(xaxis_title = 'Países')
fig10.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig10)
Vale lembrar que prever o desenvolvimento de um jogador é uma tarefa bem difícil, pois nem sempre eles evoluem como o previsto. Além disso, existem vários jovens surgindo sempre, incluindo em ligas não cadastradas no jogo ou em categorias de base (por isso países com alta revelação de bons jogadores como Argentina e Brasil não aparecem com tanto destaque). Portanto, é errado entender esses dados como extremamente precisos, já que o potencial de um atleta é flexível e imprevisivel.
Agora focaremos mais nos clubes, começando pelos que tem mais jogadores, depois overall médio e folhas salariais.
#Excluindo jogadores "Free agent" (Sem clube)
dfd = df[df['Club Name'] != 'Free agent']
#Criando variável que contém a quantidade de jogadores por clube
clubs = dfd['Club Name'].value_counts()
#Criando gráfico
fig11 = px.bar(clubs.head(10), title = 'Clubes com mais jogadores')
fig11.update_layout(xaxis_title = 'Clubes')
fig11.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig11)
#Aqui excluí um time que ficou com a média alta por ter poucos jogadores
dfe = df[df['Club Name'] != 'AFC Richmond']
#Criando variável com os valores ordenados das clubes com maiores médias de Overall
clubs_ovr = dfe.groupby('Club Name').Overall.mean().sort_values(ascending = False)
#Criando gráfico
fig12 = px.bar(clubs_ovr.head(10), title = 'Clubes por Overall')
fig12.update_layout(xaxis_title = 'Clubes')
fig12.update_layout(yaxis_title = 'Quantidade')
fig12.update_traces(marker=dict(color='purple'))
pyo.iplot(fig12)
Veremos os clubes mais valiosos a partir da soma dos salários de todos os jogadores (folha salarial).
#Criando variável agrupando por clube e ordenando pelo valor da soma dos salários
sals = df.groupby('Club Name')['Wage'].sum().sort_values(ascending = False)
#Criando gráfico
fig13 = px.bar(sals.head(), title = 'Clubes mais valiosos')
fig13.update_layout(xaxis_title = 'Clubes')
fig13.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig13)
Nesse tipo de análise vemos as interações entre duas ou mais variáveis, medindo suas correlações e dispersões. Primeiramente, utilizaremos a função "corr" do pandas para ver as correlações entre as colunas.
A correlação de Pearson (ou simplesmente "correlação") é uma estatística descritiva que mede o grau de associação entre duas variáveis, indo de -1 (correlação negativa) e 1 (correlação perfeita). Quanto mais próximo de 1, maior a correlação entre duas variáveis e, quanto mais próximo de -1 menor ela é. Porém, caso o valor seja próximo ou igual a zero, não há correlação linear entre as variáveis, só podendo existir uma correlação não-linear.
#Calculando a correlação geral do Dataframe
df.corr(numeric_only = True)
| Overall | Potential | Value | Age | Height(in cm) | Weight(in kg) | TotalStats | BaseStats | Wage | Release Clause | Pace Total | Shooting Total | Passing Total | Dribbling Total | Defending Total | Physicality Total | Crossing | Finishing | Heading Accuracy | Short Passing | Volleys | Dribbling | Curve | Freekick Accuracy | LongPassing | BallControl | Acceleration | Sprint Speed | Agility | Reactions | Balance | Shot Power | Jumping | Stamina | Strength | Long Shots | Aggression | Interceptions | Positioning | Vision | Penalties | Composure | Marking | Standing Tackle | Sliding Tackle | Goalkeeper Diving | Goalkeeper Handling | GoalkeeperKicking | Goalkeeper Positioning | Goalkeeper Reflexes | ST Rating | LW Rating | LF Rating | CF Rating | RF Rating | RW Rating | CAM Rating | LM Rating | CM Rating | RM Rating | LWB Rating | CDM Rating | RWB Rating | LB Rating | CB Rating | RB Rating | GK Rating | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Overall | 1.000000 | 0.660630 | 0.561642 | 0.442369 | 0.033137 | 0.131420 | 0.608002 | 0.843720 | 0.599129 | 0.531458 | 0.252837 | 0.465057 | 0.699315 | 0.674971 | 0.362324 | 0.560813 | 0.395435 | 0.331967 | 0.342452 | 0.520784 | 0.367168 | 0.376185 | 0.416575 | 0.374162 | 0.507192 | 0.457705 | 0.198758 | 0.213367 | 0.254826 | 0.872789 | 0.142749 | 0.552518 | 0.282737 | 0.376994 | 0.353857 | 0.392187 | 0.393433 | 0.311216 | 0.348038 | 0.523290 | 0.331834 | 0.700583 | 0.313975 | 0.266683 | 0.240499 | -0.016593 | -0.013655 | -0.016764 | -0.008318 | -0.013110 | 0.480301 | 0.447831 | 0.475105 | 0.475105 | 0.475105 | 0.447831 | 0.489274 | 0.472606 | 0.541536 | 0.472606 | 0.451583 | 0.479747 | 0.451583 | 0.428254 | 0.400783 | 0.428254 | 0.044462 |
| Potential | 0.660630 | 1.000000 | 0.532835 | -0.263686 | 0.017489 | -0.003973 | 0.372469 | 0.526546 | 0.497392 | 0.509867 | 0.288590 | 0.281073 | 0.448553 | 0.501373 | 0.180526 | 0.205186 | 0.244649 | 0.227078 | 0.195108 | 0.376854 | 0.228954 | 0.302802 | 0.269170 | 0.207204 | 0.338221 | 0.346017 | 0.220052 | 0.225343 | 0.205465 | 0.539246 | 0.131779 | 0.337282 | 0.087303 | 0.187141 | 0.081426 | 0.232690 | 0.186599 | 0.155149 | 0.226827 | 0.352757 | 0.201297 | 0.427722 | 0.157665 | 0.156970 | 0.142714 | -0.039719 | -0.040237 | -0.040616 | -0.037519 | -0.038448 | 0.330398 | 0.326722 | 0.339944 | 0.339944 | 0.339944 | 0.326722 | 0.359247 | 0.348049 | 0.370327 | 0.348049 | 0.291078 | 0.294840 | 0.291078 | 0.270494 | 0.227643 | 0.270494 | -0.002057 |
| Value | 0.561642 | 0.532835 | 1.000000 | 0.030662 | 0.008028 | 0.027106 | 0.341551 | 0.468076 | 0.822262 | 0.976244 | 0.205576 | 0.275255 | 0.399985 | 0.406424 | 0.163425 | 0.234945 | 0.230049 | 0.216025 | 0.167989 | 0.304244 | 0.233128 | 0.241773 | 0.253454 | 0.210590 | 0.291490 | 0.273427 | 0.159242 | 0.166743 | 0.170707 | 0.498667 | 0.120730 | 0.303484 | 0.112006 | 0.197522 | 0.129648 | 0.227479 | 0.187351 | 0.145640 | 0.220491 | 0.329637 | 0.190236 | 0.391234 | 0.145681 | 0.131331 | 0.112650 | -0.026560 | -0.026122 | -0.024337 | -0.024374 | -0.023352 | 0.292802 | 0.279449 | 0.293238 | 0.293238 | 0.293238 | 0.279449 | 0.306244 | 0.295886 | 0.321575 | 0.295886 | 0.252712 | 0.259591 | 0.252712 | 0.234933 | 0.202809 | 0.234933 | 0.011339 |
| Age | 0.442369 | -0.263686 | 0.030662 | 1.000000 | 0.066684 | 0.217895 | 0.246279 | 0.381901 | 0.144251 | 0.025078 | -0.144474 | 0.253085 | 0.338708 | 0.215832 | 0.225600 | 0.440695 | 0.124869 | 0.083500 | 0.156620 | 0.144434 | 0.138420 | 0.024946 | 0.141496 | 0.180766 | 0.188503 | 0.089223 | -0.135626 | -0.125666 | -0.019026 | 0.434187 | -0.050771 | 0.267892 | 0.236982 | 0.133382 | 0.343639 | 0.155305 | 0.239378 | 0.173657 | 0.092903 | 0.200278 | 0.144097 | 0.348245 | 0.168584 | 0.106238 | 0.093218 | 0.100972 | 0.106347 | 0.102898 | 0.111290 | 0.104034 | 0.132588 | 0.086605 | 0.111920 | 0.111920 | 0.111920 | 0.086605 | 0.108152 | 0.091072 | 0.166533 | 0.091072 | 0.141274 | 0.193036 | 0.141274 | 0.142184 | 0.183151 | 0.142184 | 0.132966 |
| Height(in cm) | 0.033137 | 0.017489 | 0.008028 | 0.066684 | 1.000000 | 0.754845 | -0.382480 | -0.123239 | 0.025430 | 0.006404 | -0.373351 | -0.084751 | -0.180343 | -0.271559 | 0.037421 | 0.409400 | -0.501520 | -0.382351 | 0.008303 | -0.342818 | -0.355246 | -0.480466 | -0.457941 | -0.430508 | -0.319053 | -0.402082 | -0.543262 | -0.448808 | -0.633949 | 0.001989 | -0.767247 | -0.169045 | 0.026047 | -0.300078 | 0.522558 | -0.399726 | -0.073005 | -0.094095 | -0.446303 | -0.369882 | -0.341398 | -0.184355 | -0.099398 | -0.110241 | -0.111459 | 0.366696 | 0.364998 | 0.362319 | 0.361931 | 0.363832 | -0.368263 | -0.480017 | -0.438248 | -0.438248 | -0.438248 | -0.480017 | -0.449370 | -0.464597 | -0.387355 | -0.464597 | -0.321388 | -0.212100 | -0.321388 | -0.271875 | -0.088695 | -0.271875 | 0.369929 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| RWB Rating | 0.451583 | 0.291078 | 0.252712 | 0.141274 | -0.321388 | -0.257192 | 0.885559 | 0.470957 | 0.271175 | 0.238489 | 0.151705 | -0.160019 | 0.259710 | 0.159003 | 0.723959 | 0.349887 | 0.795186 | 0.479392 | 0.709170 | 0.869402 | 0.513274 | 0.758276 | 0.686218 | 0.619042 | 0.830357 | 0.824810 | 0.591191 | 0.593017 | 0.570948 | 0.476829 | 0.532420 | 0.355972 | 0.341459 | 0.838713 | 0.254454 | 0.592792 | 0.791688 | 0.853604 | 0.638783 | 0.524084 | 0.514528 | 0.682670 | 0.862314 | 0.859867 | 0.841383 | -0.766415 | -0.763568 | -0.763878 | -0.761488 | -0.765552 | 0.732549 | 0.769684 | 0.746306 | 0.746306 | 0.746306 | 0.769684 | 0.780057 | 0.819394 | 0.896510 | 0.819394 | 1.000000 | 0.977241 | 1.000000 | 0.993319 | 0.927139 | 0.993319 | -0.744169 |
| LB Rating | 0.428254 | 0.270494 | 0.234933 | 0.142184 | -0.271875 | -0.215549 | 0.840970 | 0.433111 | 0.253928 | 0.222359 | 0.100806 | -0.235150 | 0.204396 | 0.082624 | 0.783949 | 0.384640 | 0.736066 | 0.400156 | 0.718136 | 0.828250 | 0.441013 | 0.690395 | 0.619006 | 0.556380 | 0.798432 | 0.770106 | 0.538110 | 0.547548 | 0.504430 | 0.455845 | 0.476196 | 0.291748 | 0.364581 | 0.815013 | 0.290724 | 0.521038 | 0.809376 | 0.896324 | 0.566065 | 0.452945 | 0.450396 | 0.644653 | 0.903601 | 0.905184 | 0.889880 | -0.745071 | -0.742363 | -0.743158 | -0.740329 | -0.744323 | 0.668854 | 0.700366 | 0.676994 | 0.676994 | 0.676994 | 0.700366 | 0.712892 | 0.755647 | 0.849648 | 0.755647 | 0.993319 | 0.984470 | 0.993319 | 1.000000 | 0.959383 | 1.000000 | -0.724081 |
| CB Rating | 0.400783 | 0.227643 | 0.202809 | 0.183151 | -0.088695 | -0.044569 | 0.720341 | 0.353803 | 0.229538 | 0.192411 | -0.090421 | -0.346965 | 0.101544 | -0.070391 | 0.877260 | 0.521944 | 0.557062 | 0.229739 | 0.742060 | 0.723283 | 0.287786 | 0.515448 | 0.449180 | 0.407878 | 0.712590 | 0.629772 | 0.334348 | 0.363651 | 0.294975 | 0.432366 | 0.282916 | 0.185968 | 0.430265 | 0.721308 | 0.450186 | 0.364031 | 0.856911 | 0.947824 | 0.393360 | 0.301049 | 0.315045 | 0.571834 | 0.953673 | 0.953278 | 0.937945 | -0.656437 | -0.653725 | -0.655322 | -0.651969 | -0.655857 | 0.520290 | 0.519606 | 0.507501 | 0.507501 | 0.507501 | 0.519606 | 0.545751 | 0.584842 | 0.725680 | 0.584842 | 0.927139 | 0.967690 | 0.927139 | 0.959383 | 1.000000 | 0.959383 | -0.635901 |
| RB Rating | 0.428254 | 0.270494 | 0.234933 | 0.142184 | -0.271875 | -0.215549 | 0.840970 | 0.433111 | 0.253928 | 0.222359 | 0.100806 | -0.235150 | 0.204396 | 0.082624 | 0.783949 | 0.384640 | 0.736066 | 0.400156 | 0.718136 | 0.828250 | 0.441013 | 0.690395 | 0.619006 | 0.556380 | 0.798432 | 0.770106 | 0.538110 | 0.547548 | 0.504430 | 0.455845 | 0.476196 | 0.291748 | 0.364581 | 0.815013 | 0.290724 | 0.521038 | 0.809376 | 0.896324 | 0.566065 | 0.452945 | 0.450396 | 0.644653 | 0.903601 | 0.905184 | 0.889880 | -0.745071 | -0.742363 | -0.743158 | -0.740329 | -0.744323 | 0.668854 | 0.700366 | 0.676994 | 0.676994 | 0.676994 | 0.700366 | 0.712892 | 0.755647 | 0.849648 | 0.755647 | 0.993319 | 0.984470 | 0.993319 | 1.000000 | 0.959383 | 1.000000 | -0.724081 |
| GK Rating | 0.044462 | -0.002057 | 0.011339 | 0.132966 | 0.369929 | 0.344316 | -0.648967 | 0.078930 | 0.013433 | 0.014015 | -0.060873 | 0.288931 | 0.220301 | 0.187807 | -0.261143 | 0.023738 | -0.667654 | -0.605826 | -0.738352 | -0.716263 | -0.594482 | -0.768641 | -0.616438 | -0.569212 | -0.579861 | -0.787955 | -0.635932 | -0.637259 | -0.563696 | -0.022147 | -0.540291 | -0.245527 | -0.213373 | -0.695350 | -0.111834 | -0.610950 | -0.588176 | -0.506051 | -0.693344 | -0.328987 | -0.622415 | -0.432213 | -0.548571 | -0.550053 | -0.531734 | 0.987338 | 0.986737 | 0.978658 | 0.986624 | 0.987912 | -0.728235 | -0.738402 | -0.717813 | -0.717813 | -0.717813 | -0.738402 | -0.717090 | -0.750672 | -0.725650 | -0.750672 | -0.744169 | -0.677267 | -0.744169 | -0.724081 | -0.635901 | -0.724081 | 1.000000 |
67 rows × 67 columns
Como temos muitas linhas e colunas, fica difícil conseguir analisar bem essa tabela de correlação, mas veremos as mais importantes mais à frente. Por enquanto olharemos os gráficos de dispersão de algumas variáveis relevantes.
#Criando gráfico de dispersão entre overall e idade
figb = px.scatter(df, x = 'Overall', y = 'Age', color = 'Overall', title = 'Overall por Idade', trendline="ols")
figb.update_layout(yaxis_title='Idade')
pyo.iplot(figb)
Aqui observamos que existe uma tendência natural, e esperada, de crescimento do Overall conforme o aumento da idade. Apenas um jogador com menos de 25 anos possui mais de 90 de rating e somente um com mais de 40 anos tem um rating próximo a 80.
#Criando gráfico de dispersão entre salário e overall
figc = px.scatter(df, x='Wage', y='Overall', color='Wage', trendline = "ols", title = 'Salário x Overall')
figc.update_layout(xaxis_title='Salário')
pyo.iplot(figc)
Nesta dispersão, também vemos uma natural correlação positiva entre Overall e Salário, apesar de alguns valores discrepantes dos demais.
#Criando gráfico
figd = px.scatter(df, x='Value', y='Age', color='Value', trendline = 'ols', title ='Valor x Idade')
figd.update_layout(xaxis_title='Valor')
figd.update_layout(yaxis_title='Idade')
pyo.iplot(figd)
Na relação entre Idade e Valor, constatamos que existe uma correlação linear um pouco mais baixa do que se poderia imaginar. Com o passar do tempo, é natural que os atletas percam seu valor de mercado, já que seus atributos físicos costumam diminuir. Esse fenômeno ocorre aqui, mas não de forma linear, o que nos faz crer que existe uma correlação não-linear entre as duas variáveis. Outro fator que contribui para isso é que Overall e Idade não são necessariamente proporcionais, ou seja, parte considerável dos jogadores mantém suas qualidades por mais tempo.
#Criando gráfico
fige = px.scatter(df, x ='Potential', y = 'Value', color='Value', trendline = 'ols')
pyo.iplot(fige)
Apesar de alguns valores discrepantes, aqui também não vemos nada anormal, jogadores com maior potencial valem mais no mercado.
Para checarmos a distribuição salarial dos 5 clubes mais valiosos, usaremos o boxplot. Basicamente, as extremidades são os valores maiores e menores , a mediana dos valores é o traço dentro do retângulo ("box") e extremidades dele são o primeiro (parte inferior) e terceiro (parte superior) quartis, que representam - respectivamente-, 25% e 75% dos valores.
#Criando Dataframe apenas com o jogadores dos 5 clubes mais valiosos
df_clbs = df_clubs = df[df['Club Name'].isin(['Real Madrid CF', 'Manchester City', 'FC Barcelona',
'Liverpool', 'Manchester United'])]
#Criando gráfico boxplot
fig14 = px.box(df_clbs, x = 'Club Name', y = 'Wage', title = 'Distribuição de salários entre os 5 primeiros em folha salarial')
fig14.update_layout(xaxis_title = 'Clubes')
fig14.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig14)
O ponto fora do gráfico Boxplot do Barcelona representa um Outlier (Valor discrepante em relação aos demais), o que indica que existe uma certa disparidade salarial no clube. O gráfico do Real Madrid também possui pontos bem altos, porém, como não existem Outliers, entendemos que a diferença entre os salários não é tão grande e, caso exista, não é responsável por apenas um jogador como no caso do Barcelona.
Agora que já temos uma boa visão geral sobre o conjunto de dados, podemos tentar buscar respostas para nossas perguntas e hipóteses criadas no início da análise. Primeiro tentando identificar quais são os jogadores mais habilidosos e velozes do game.
-> Quais são os jogadores mais rápidos e habilidosos?
Para isso, escolheremos colunas que representam atributos relacionados a velocidade e habilidade geral. Como: Pace Total, Dribbling Total, Dribbling, etc...
hab = df.loc[:, ['Known As','Nationality', 'Pace Total', 'Dribbling Total', 'Dribbling', 'Acceleration', 'Sprint Speed',
'Agility', 'Reactions', 'BallControl', 'Balance']]
hab.rename(columns = {'Known As': 'Jogador', 'Nationality':'Nacionalidade'}, inplace = True)
hab['Habilidade Geral'] = (hab['Dribbling Total'] + hab['Reactions'] + hab['Dribbling'] + hab['BallControl'] + hab['Balance'])/5
hab['Velocidade Geral'] = (hab['Pace Total'] + hab['Acceleration'] + hab['Agility'] + hab['Reactions'] + hab['Sprint Speed'])/5
top_hab = hab.sort_values(by = 'Habilidade Geral', ascending = False)
top_hab.head(10).loc[:, ['Jogador', 'Nacionalidade', 'Habilidade Geral']]
# JOGADORES COM MAIS HABILIDADE GERAL
| Jogador | Nacionalidade | Habilidade Geral | |
|---|---|---|---|
| 0 | L. Messi | Argentina | 93.8 |
| 36 | M. Verratti | Italy | 90.8 |
| 23 | Bernardo Silva | Portugal | 90.8 |
| 11 | Neymar Jr | Brazil | 90.4 |
| 5 | M. Salah | Egypt | 90.4 |
| 4 | K. Mbappé | France | 90.0 |
| 43 | Thiago | Spain | 89.0 |
| 29 | L. Modrić | Croatia | 88.6 |
| 48 | R. Mahrez | Algeria | 88.4 |
| 49 | P. Dybala | Argentina | 88.4 |
top_spd = hab.sort_values(by = 'Velocidade Geral', ascending = False)
top_spd.head(10).loc[:, ['Jogador', 'Nacionalidade', 'Velocidade Geral']]
# JOGADORES COM MAIS VELOCIDADE GERAL
| Jogador | Nacionalidade | Velocidade Geral | |
|---|---|---|---|
| 4 | K. Mbappé | France | 95.4 |
| 63 | Vinícius Jr. | Brazil | 92.2 |
| 15 | S. Mané | Senegal | 91.0 |
| 47 | R. Sterling | England | 91.0 |
| 56 | K. Coman | France | 90.8 |
| 141 | A. Davies | Canada | 90.6 |
| 5 | M. Salah | Egypt | 90.6 |
| 402 | J. Frimpong | Netherlands | 90.0 |
| 155 | O. Dembélé | France | 89.6 |
| 1109 | F. Acheampong | Ghana | 89.6 |
-> Jogadores brasileiros (ou sulamericanos) são naturalmente mais habilidosos que os de outras nações.
Com esses dados de habilidade geral, que inclui os atributos: Dribbling Total (Média dos atributos de drible), Reactions (Velocidade de reação), Dribbbling (Drible), Ball Control (Controle de Bola) e Balance (Controle de bola após uma disputa - influencia o drible), podemos validar ou não esta hipótese.
# Criando dataframe com países e quantidade de jogadores
dfg = df.groupby("Nationality").size().reset_index(name='counts')
dfg = dfg[dfg['counts'] > 150]
# Lista contendo os países com mais de 100 jogadores
g = dfg.iloc[:, 0]
nac_hab = top_hab[top_hab['Nacionalidade'].isin(g)]
nac_hab = nac_hab.groupby('Nacionalidade')['Habilidade Geral'].mean()
nac_hab = nac_hab.sort_values(ascending = False)
fig15 = px.bar(nac_hab.head(10), title = 'Média de Habilidade Geral por país')
fig15.update_traces(marker=dict(color='gold'))
fig15.update_layout(xaxis_title = 'Países')
fig15.update_layout(yaxis_title = 'Quantidade')
pyo.iplot(fig15)
Como podemos ver, a hipótese é verdadeira , os jogadores brasileiros aparecem (com uma leve diferença) em primeiro no gráfico, que também contém mais dois países sulamericanos no top 5 (Argentina e Colômbia).
-> Jogadores com maiores TotalStats (Soma de todos os atributos) possuem Overalls mais altos.
Isso é lógico de se pensar, já que a nota de Overall reflete a qualidade dos atributos do jogador. Mas será que essas duas métricas são realmente proporcionais?
#Criando Dataframe só com as colunas TotalStats e Overall
sta_ovr = df.loc[:, ['TotalStats', 'Overall']]
#Criando gráfico de dispersão
fig16 = px.scatter(sta_ovr, x = 'Overall', y = 'TotalStats', color = 'TotalStats', trendline="ols")
pyo.iplot(fig16)
#Calculando a correlação geral
sta_ovr.corr()
| TotalStats | Overall | |
|---|---|---|
| TotalStats | 1.000000 | 0.608002 |
| Overall | 0.608002 | 1.000000 |
Aplicando o scatter plot entre Overall e TotalStats e usando o atributo "trendline = ols", observamos que há uma relação linear (estimada pela linha) entre essas duas características com o R-quadrado aproximadamente igual a 37% (0,369). Neste caso, esse valor representa o quão bem a variação do Overall acompanha a variação do TotalStats. Já a correlação indica a força da relação entre as variáveis, variando entre -1 (Correlação Negativa) e 1 (Correlação Positiva), que foi de 0,608. Conclusão: existe uma correlação, mas ela é menor do que naturalmente se espera.
Já que não tivemos uma correspondência tão grande entre TotalStats e os ratings dos jogadores, podemos verificar o mesmo para o atributo BaseStats, que é equivalente a soma dos atributos Pace Total (Média dos atributos de velocidade), Shooting Total (Média dos atributos de chute), Passing Total (Média dos atributos de passe), Dribbling Total (Média dos atributos de drible), Defending Total (Média dos atributos de defesa) e Physicality Total (Média dos atributos físicos).
Como o BaseStats só leva em conta poucos dados (ao contrário do TotalStats), é natural que observemos uma correlação mais próxima de 1 (positiva) e um gráfico de dispersão que evidencie isso.
#Criando gráfico de dispersão
fig17 = px.scatter(df, x = 'Overall', y = 'BaseStats', color = 'Overall', title = 'BaseStats x Overall', trendline = 'ols')
pyo.iplot(fig17)
#Criando Dataframe só com BaseStats e overall
Bsta = df.loc[:, ['BaseStats', 'Overall']]
#Calculando correlação
Bsta.corr()
| BaseStats | Overall | |
|---|---|---|
| BaseStats | 1.00000 | 0.84372 |
| Overall | 0.84372 | 1.00000 |
Agora, com BaseStats, vemos uma relação mais consistente entre as variáveis. Através da trendline, observamos que o R-quadrado é de 0.711 (71,1%), o que indica uma boa relação linear e, pela função corr, uma correlação de 0.84 (0.2 maior que a da TotalStats). Com isso, concluímos que esse atributo reflete mais a qualidade dos atletas no game.
-> Atributos que mais contribuem com o rating (Overall)
#Criando Dataframes com as colunas de atributos e a de Overall
att = df.iloc[:, 21:61]
ovr = df['Overall']
#Juntando os Dataframes
att = pd.concat([ovr, att], axis = 1)
#Calculando a correlação entre Overall e atributos e ordenando os valores
corrs1 = att.corr(numeric_only = True)
corrs = corrs1['Overall'].sort_values(ascending = False)
#Vendo os 10 maiores valores
corrs.head(10)
Overall 1.000000 Reactions 0.872789 Composure 0.700583 Passing Total 0.699315 Dribbling Total 0.674971 Physicality Total 0.560813 Shot Power 0.552518 Vision 0.523290 Short Passing 0.520784 LongPassing 0.507192 Name: Overall, dtype: float64
Como resultado, temos que os atributos com maior influência no rating de um jogador são: Reactions (Velocidade de reação), Composure (Controle mental), Passing Total (Média de atributos de passe) e Dribbling Total (Média de atributos de drible). Após isso, Physicality Total (Média dos atributos físicos), Shot Power (Força de chute), dentre outros. A conclusão que temos é que, além de atributos físicos, os melhores jogadores também possuem uma boa mentalidade e habilidade emocional.
#Vendo os 10 menores valores
corrs.tail(10)
Pace Total 0.252837 Sliding Tackle 0.240499 Sprint Speed 0.213367 Acceleration 0.198758 Balance 0.142749 Goalkeeper Positioning -0.008318 Goalkeeper Reflexes -0.013110 Goalkeeper Handling -0.013655 Goalkeeper Diving -0.016593 GoalkeeperKicking -0.016764 Name: Overall, dtype: float64
Entre os atributos menos correlacionados, naturalmente estão os que pertencem aos goleiro, mas também os relacionados a velocidade.
Por fim, criei uma mapa de calor para entendermos a correlação geral entre os atributos e o Overall, onde as cores mais claras representam uma correlação mais forte.
#Criando um mapa de calor
heat = px.imshow(corrs1)
heat.update_layout(height = 600, width = 790)
pyo.iplot(heat)
Apesar de não ser um conjunto de dados complexo e um pouco distante da realidade e seus problemas, acredito que foi possível tirar bons insigths e testar algumas coisa com eles. Além de uma análise exploratória, é possível também aplicar técnicas mais avançadas de estatística e machine learning para, por exemplo, fazer previsões sobre o salário ou o valor de algum jogador baseado em seus atributos e características. Além de sistemas de recomendação das melhores escalações ou de jogadores para serem comprados pelos usuários em suas gameplays e análise para a descobertas de jogadores com potencial de crescimento elevado e que podem se tornam atletas de elite no cenário internacional.
Creio que atingi todos os objetivos que criei e utilizei as melhores maneiras de visualização de dados que tenho conhecimento (ponto que pode ser melhorado ainda mais). Por ser meu projeto desse tipo, fiquei com bastante dúvida sobre o que colocar e aceito sugestões e feedback sobre minha análise. Pretendo fazer mais projetos como esse, além de outros voltados a machine learning (regressão, classificação, clusterização, etc..) no futuro a partir da continuação dos meus estudos sobre data science. Muito obrigado por ler e até mais! ;)